----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    10:14:28 11/14/2010 
-- Design Name: 
-- Module Name:    testUART - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity testUART is
    Port ( Serial_Out : out  STD_LOGIC;
			  Serial_In : in STD_LOGIC;
			  Clock_IN : in  STD_LOGIC;
			  LED		: out std_logic_vector(7 downto 0) :="00000000";
			  Reset_IN : in STD_LOGIC);
end testUART;

architecture Behavioral of testUART is



COMPONENT tx_uart
	PORT(
		TX_REG_8_BIT_IN : IN std_logic_vector(7 downto 0);
		CLOCK_IN : IN std_logic;
		RESET_IN : IN std_logic;
		WR_EN : IN std_logic;          
		TX_OUT : OUT std_logic;
		TICKSIGNAL_IN : in STD_LOGIC;
		WR_READY_OUT : OUT std_logic
		);
	END COMPONENT;

COMPONENT rx_uart
	PORT(
		RX_IN : IN std_logic;
		CLOCK_IN : IN std_logic;
		RESET_IN : IN std_logic;          
		FIFO_18_BIT_OUT : OUT std_logic_vector(17 downto 0);
		READ_MESSAGE_IN : IN std_logic;
		MESSAGE_READY_OUT : OUT std_logic;
		VALID_OUT : OUT std_logic;
		TICKSIGNAL_OUT : OUT std_logic
		);
	END COMPONENT;
	
	COMPONENT Clock_29MHZ
	PORT(
			 CLKIN_IN        : in    std_logic; 
          RST_IN          : in    std_logic; 
          CLKFX_OUT       : out   std_logic; 
          CLKIN_IBUFG_OUT : out   std_logic; 
          CLK0_OUT        : out   std_logic; 
          LOCKED_OUT      : out   std_logic
		);
	END COMPONENT;
	
--constants
constant MID1 : std_logic_vector(15 downto 0) := x"0001";

--TX signals
signal transmit : std_logic_vector(7 downto 0) := "00000000"; --Send char '1'
signal wrr : std_logic;
signal wrr_ready : std_logic;

--RX signals
signal rdd : std_logic;
signal rdd_ready : std_logic;
--signal serial_in : std_logic;
signal receive : std_logic_vector(17 downto 0) := "000000000000000000";
signal receive_reg : std_logic_vector(15 downto 0);
signal ticksignal_s : std_logic;

signal clock_ref : std_logic;
signal clock_reset : std_logic; --must assert for 3 clock cycles
signal clock0 : std_logic;
signal cnt : std_logic_vector(2 downto 0) := "000";

--FIFO
--signal din : std_logic_vector(15 downto 0);
signal start_msg : std_logic;
signal end_msg : std_logic;          
--signal dout : std_logic_vector(15 downto 0);
signal valid_in : std_logic;
--signal empty : std_logic;
signal lower_byte :std_logic := '0';
signal set_lower_byte :std_logic := '0';
signal reset_lower_byte :std_logic := '0';

signal led_sig : std_logic_vector(7 downto 0);

type mainState is (
		stIdle,
		stFifo0,
		stFifo1,
		stFifo2,
		stFifo3,
		stSend);
		
signal stCur	:	mainState := stIdle;
	


begin
					
	Inst_tx_uart: tx_uart PORT MAP(
		TX_OUT => Serial_Out,
		TX_REG_8_BIT_IN => transmit,
		CLOCK_IN => clock_ref,
		RESET_IN => RESET_IN,
		WR_EN =>  wrr,
		TICKSIGNAL_IN => ticksignal_s,
		WR_READY_OUT => wrr_ready
	);
	
	Inst_rx_uart: rx_uart PORT MAP(
		RX_IN => Serial_In,
		FIFO_18_BIT_OUT => receive,
		CLOCK_IN => clock_ref,
		MESSAGE_READY_OUT => rdd_ready,
		READ_MESSAGE_IN => rdd,
		TICKSIGNAL_OUT => ticksignal_s,
		VALID_OUT => valid_in,
		RESET_IN => RESET_IN
	);
	
	Inst_clock_29_MHZ: Clock_29MHZ PORT MAP(
		CLKIN_IN  => CLOCK_IN,     
		RST_IN  => '0',       
		CLKFX_OUT  => clock_ref,    
		CLKIN_IBUFG_OUT => open,
		CLK0_OUT  => open,     
		LOCKED_OUT  => open   
	);

--process(Clock)
--	begin
--		if(rising_edge(Clock)) then
--			clock_reset <= '1';
--			if(cnt = "111") then
--				clock_reset <= '0';
--			else
--				cnt <= std_logic_vector( unsigned(cnt) + 1 );
--			end if;
--		end if;
--end process;


-- process(clock_ref,Reset)
	-- begin
		-- if Reset = '1' then
			-- stCur <= stIdle;
		-- elsif(clock_ref = '1' and clock_ref'Event) then
			-- stCur <= stNext;
		-- end if;
-- end process;

--LED <= transmit(7 downto 0);
--LED <= led_sig;


process (clock_ref)
	begin
	
	if rising_edge(clock_ref) then
		start_msg <= '0';
		wrr <= '0';
		rdd <= '0';
		end_msg <= '0';
		set_lower_byte <= '0';
		reset_lower_byte <= '0';
		--if(receive(16) = '1') then
			--start_msg <= '1';
		--end if;
		
		if(receive(17) = '1') then
			end_msg <= '1';
		end if;
		
		--set that we are sending lower byte
		if(set_lower_byte = '1') then
			lower_byte <= '1';
		elsif(reset_lower_byte = '1') then
			lower_byte <= '0';
		end if;
		
		case stCur is
			when stIdle =>
				LED(0) <= '1';
				if(rdd_ready = '1' and wrr_ready = '1') then
					stCur <= stFifo0;
				else
					stCur <= stIdle;
				end if;
			when stFifo0 =>
			   LED(1) <= '1';
				rdd <= '1';
				stCur <= stFifo1;
			when stFifo1 =>
				LED(2) <= '1';
				stCur <= stFifo1;
				if(valid_in = '1') then
					receive_reg <= receive(15 downto 0);
					stCur <= stFifo2;
				end if;
			when stFifo2 =>
				LED(3) <= '1';
				transmit <= receive_reg(15 downto 8);
				wrr <= '1';
				set_lower_byte <= '1';
				stCur <= stSend;
			when stFifo3 =>
				LED(4) <= '1';
				transmit <= receive_reg(7 downto 0);
				wrr <= '1';
				stCur <= stSend;
			when stSend =>
				--wrr <= '1';
				LED(5) <= '1';
				if(wrr_ready = '0') then
					stCur <= stSend;
					LED(6) <= '1';
				else
					stCur <= stFifo0;
					LED(7) <= '1';
					if(lower_byte = '1') then
						stCur <= stFifo3;
						reset_lower_byte <= '1';
					elsif(end_msg = '1') then
						stCur <= stIdle;
					end if;
				end if;
		end case;
	end if;
end process;
		
end Behavioral;

